package cn.car.Util;

import java.io.StringReader;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

//import cn.ffcs.msweb.exception.MSException;

public class StringUtil {

	public static boolean isEmpty(String str) {
		return (str == null || str.length() == 0);
	}

	/**
	 * 替换一个字符串中的某些指定字符
	 * 
	 * @param strData
	 *            String 原始字符串
	 * @param regex
	 *            String 要替换的字符串
	 * @param replacement
	 *            String 替代字符串
	 * @return String 替换后的字符串
	 */
	public static String replaceString(String strData, String regex,
			String replacement) {
		if (strData == null) {
			return null;
		}
		int index;
		index = strData.indexOf(regex);
		String strNew = "";
		if (index >= 0) {
			while (index >= 0) {
				strNew += strData.substring(0, index) + replacement;
				strData = strData.substring(index + regex.length());
				index = strData.indexOf(regex);
			}
			strNew += strData;
			return strNew;
		}
		return strData;
	}

	/**
	 * 替换字符串中特殊字符
	 */
	public static String encodeString(String strData) {
		if (strData == null) {
			return "";
		}
		strData = replaceString(strData, "&", "&amp;");
		strData = replaceString(strData, "<", "&lt;");
		strData = replaceString(strData, ">", "&gt;");
		strData = replaceString(strData, "'", "&apos;");
		strData = replaceString(strData, "\"", "&quot;");
		return strData;
	}

	/**
	 * 还原字符串中特殊字符
	 */
	public static String decodeString(String strData) {
		strData = replaceString(strData, "&lt;", "<");
		strData = replaceString(strData, "&gt;", ">");
		strData = replaceString(strData, "&apos;", "'");
		strData = replaceString(strData, "&quot;", "\"");
		strData = replaceString(strData, "&amp;", "&");
		return strData;
	}

	public static StringBuffer decodeUnicode(String dataStr) {
		dataStr = dataStr.replace("&#x", "\\u");
		final StringBuffer buffer = new StringBuffer();
		String tempStr = "";
		String operStr = dataStr;
		if (operStr != null && operStr.indexOf("\\u") == -1)
			return buffer.append(operStr);
		if (operStr != null && !operStr.equals("")
				&& !operStr.startsWith("\\u")) {
			tempStr = operStr.substring(0, operStr.indexOf("\\u"));
			operStr = operStr.substring(operStr.indexOf("\\u"), operStr
					.length());
		}
		buffer.append(tempStr);
		while (operStr != null && !operStr.equals("")
				&& operStr.startsWith("\\u")) {
			tempStr = operStr.substring(0, 6);
			operStr = operStr.substring(7, operStr.length());
			String charStr = "";
			charStr = tempStr.substring(2, tempStr.length());
			char letter = (char) Integer.parseInt(charStr, 16);
			buffer.append(new Character(letter).toString());
			if (operStr.indexOf("\\u") == -1) {
				buffer.append(operStr);
			} else {
				tempStr = operStr.substring(0, operStr.indexOf("\\u"));
				operStr = operStr.substring(operStr.indexOf("\\u"), operStr
						.length());
				buffer.append(tempStr);
			}
		}
		return buffer;
	}

	/**
	 * 对webservice框架axis和xfire截取返回主内容，只适合于一个string参数返回的
	 * 
	 * @author hanzhg 2011-11-23 下午08:26:28
	 * 
	 * @param filestring
	 * @return
	 */
	public static String getWebServiceRsp(String filestring) {
		filestring = findRspBody(filestring);
		//使用axis的解码方法
		filestring=AxisStringUtils.unescapeNumericChar(filestring);
		if (filestring.indexOf("&lt;") > -1) {
			// 如果有特殊字符
			filestring = StringUtil.decodeString(filestring);
		}
//		// TODO: 以上方法比较简单，如果不考虑性能，可以用dom4j进行解析下，获取返回的值
//		if (filestring.indexOf("&#x") > -1) {
//			// TODO:这个方法有问题如果有中文编码
//			filestring = StringUtil.decodeUnicode(filestring).toString();
//		}
		return filestring;
	}
	

	/**
	 * 获取返回参数的body，使用dom4j解析，只返回第一个返回参数的值。
	 * 注意：如果返回参数内部是经过转义的xml字符串，则会出现问题，无法再次得到xml的结构了
	 * 其实如果body里面没有<?xml 这个头，进行解析的话是没有什么问题的，把特殊字符转义回来，再进行dom4j就可以
	 * @author hanzhg 2011-11-23 下午11:18:20
	 * 
	 * @param filestring
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String findRspBodyByDom4j(String filestring) {
		SAXReader saxReader = null;
		Document doc = null;
		saxReader = new SAXReader();
		try {
			doc = (Document) saxReader.read(new StringReader(filestring));
			Element root_element = doc.getRootElement();// <soap:Envelope>或<soapenv:Envelope>
			Iterator root_data = root_element.elementIterator();//
			while (root_data.hasNext()) {
				Element body_element = (Element) root_data.next();// <soap:Body>或<soapenv:Body>
				Iterator body_data = body_element.elementIterator();
				while (body_data.hasNext()) {
					Element method_element = (Element) body_data.next();// 一般是调用方法的节点
					Iterator method_data = method_element.elementIterator();
					while (method_data.hasNext()) {
						Element return1_element = (Element) method_data.next();// 一般就是值的输出
						return return1_element.getStringValue();
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
//			new MSException(e.getMessage(),e);
		}
		return null;
	}

	/**
	 * 获取返回参数的body，如果找不到特定的解析节点，就原样返回，后端做特殊解析
	 * 
	 * @author hanzhg 2011-11-23 下午11:18:07
	 * 
	 * @param filestring
	 * @return
	 */
	public static String findRspBody(String filestring) {
		int start = 0;
		int end = 0;
		if (filestring.indexOf("<out") > 0) {
			// xfire 的返回
			end = filestring.indexOf("</out>");
			if (filestring.indexOf("<out>") > 0) {
				// 没有命名空间的
				start = filestring.indexOf("<out>") + 5;
			} else {
				// 有命名空间的,空间申明写在后面,先依次往后试探截取100
				start = filestring.indexOf("<out");
				for (int i = 1; i < 100; i++) {
					char c = filestring.charAt(start + i);
					if (c == '>') {
						// 遇到
						start = start + i + 1;
						break;
					}
				}
			}
			filestring = filestring.substring(start, end);
		} else if (filestring.indexOf("<response") > 0) {
			// axis 的返回
			end = filestring.indexOf("</response>");
			if (filestring.indexOf("<response>") > 0) {
				// 没有命名空间的
				start = filestring.indexOf("<response>") + 10;
			} else {
				start = filestring.indexOf("<response");
				// 有命名空间的,空间申明写在后面，先依次往后试探截取100
				for (int i = 1; i < 100; i++) {
					char c = filestring.charAt(start + i);
					if (c == '>') {
						// 遇到
						start = start + i + 1;
						break;
					}
				}
				// TODO :如果找不到结束标记，这里没有做异常，一般来说不会有问题的
			}
			filestring = filestring.substring(start, end);
		}else if(filestring.indexOf(":out>") > 0){
			//out是有命名空间的，空间申明写在前面 如<ns1:out>
			start=filestring.indexOf(":out>")+5;//这个是确定的
			end = filestring.substring(start,filestring.length()).indexOf(":out>");//截取新的字符串，找到结尾的点
			for (int i = 1; i < 100; i++) {
				char c = filestring.charAt(end - i);
				if (c == '<') {
					// 遇到
					end = end - i ;
					break;
				}
			}
			filestring = filestring.substring(start, start+end);
		}else {
			// TODO:没有获取到输出的body，后面的截取代码自己考虑吧
			
		}
		return filestring;
	}
	
}
